package com.dxj1992.utils.UserAsset;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.dxj1992.entity.UserAsset;
import com.dxj1992.entity.UserAssetFlow;
import com.dxj1992.service.IUserAssetFlowService;
import com.dxj1992.service.IUserAssetService;
import com.dxj1992.utils.spring.SpringUtils;
import lombok.Data;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Map;

@Data
public abstract class Asset {
    // 1.加款 2.提现 3.冻结 4.解冻 5.收入 6.支出
    public static final Long TYPE_RECHARGE = 1L;
    public static final Long TYPE_WITHDRAW = 2L;
    public static final Long TYPE_FREEZE = 3L;
    public static final Long TYPE_UNFREEZE = 4L;
    public static final Long TYPE_INCOME = 5L;
    public static final Long TYPE_EXPEND = 6L;

    public static final String TRADE_MODEL_ID = "tradeModelId";
    public static final String TRADE_MODEL = "tradeModel";

    // 用户ID
    private Long userId;
    // 交易类型
    private Long type;
    // 交易子类型
    private Long subType;
    // 交易单号
    private String tradeNo;
    // 交易金额
    private Double amount;
    // 备注
    private String remark;

    // 用户资产对象
    private UserAsset userAsset;
    // 用户资产服务类
    private IUserAssetService iUserAssetService = SpringUtils.getBean("IUserAssetService");
    // 用户流水服务类
    private IUserAssetFlowService iUserAssetFlowService = SpringUtils.getBean("IUserAssetFlowService");

    // 交易对象
    private Map<String, String> tradeModel;
    // 扣款来源。调用expend和consume方法时有效。可选项: balance (余额), frozen (冻结)。默认从余额扣款
    private String expendFrom;

    public void init(Long userId, Long subType, String tradeNo, Double amount, String remark) {
        this.userId = userId;
        this.subType = subType;
        this.tradeNo = tradeNo;
        this.amount = amount;
        this.remark = remark;

        this.userAssetIsExist();
        this.beforeUser();
        this.updateUserAsset();
        this.createUserAmountFlow();
    }

    public void init(Long userId, Long subType, String tradeNo, Double amount, String remark, Map<String, String> tradeModel) {
        this.userId = userId;
        this.subType = subType;
        this.tradeNo = tradeNo;
        this.amount = amount;
        this.remark = remark;
        this.tradeModel = tradeModel;

        this.userAssetIsExist();
        this.beforeUser();
        this.updateUserAsset();
        this.createUserAmountFlow();
    }

    public void init(Long userId, Long subType, String tradeNo, Double amount, String remark, String expendFrom) {
        this.userId = userId;
        this.subType = subType;
        this.tradeNo = tradeNo;
        this.amount = amount;
        this.remark = remark;
        this.expendFrom = expendFrom;

        this.userAssetIsExist();
        this.beforeUser();
        this.updateUserAsset();
        this.createUserAmountFlow();
    }

    // 用户前置操作
    public abstract void beforeUser();
    // 写用户流水
    public void createUserAmountFlow() {
        UserAssetFlow userAssetFlow = new UserAssetFlow();
        userAssetFlow.setUserId(this.getUserId().intValue());
        userAssetFlow.setType(this.getType().intValue());
        userAssetFlow.setSubType(this.getSubType().intValue());
        userAssetFlow.setTradeNo(this.getTradeNo());
        userAssetFlow.setAmount(BigDecimal.valueOf(this.getAmount()));
        userAssetFlow.setBalance(this.getUserAsset().getBalance());
        userAssetFlow.setFrozen(this.getUserAsset().getFrozen());
        userAssetFlow.setTotalRecharge(this.getUserAsset().getTotalRecharge());
        userAssetFlow.setTotalWithdraw(this.getUserAsset().getTotalWithdraw());
        userAssetFlow.setTotalConsume(this.getUserAsset().getTotalConsume());
        userAssetFlow.setTotalExpend(this.getUserAsset().getTotalExpend());
        userAssetFlow.setTotalIncome(this.getUserAsset().getTotalIncome());
        userAssetFlow.setTotalRefund(this.getUserAsset().getTotalRefund());
        userAssetFlow.setRemark(this.getRemark());
        userAssetFlow.setDate(LocalDate.now());
        userAssetFlow.setCreatedAt(LocalDateTime.now());
        userAssetFlow.setUpdatedAt(LocalDateTime.now());
        if (this.tradeModel != null) {
            userAssetFlow.setFlowableId(Long.valueOf(tradeModel.get(TRADE_MODEL_ID)));
            userAssetFlow.setFlowableType(tradeModel.get(TRADE_MODEL));
        }
        this.iUserAssetFlowService.save(userAssetFlow);
    }
    // 更新用户流水
    public abstract void updateUserAsset();
    // 判断用户资产是否存在
    public void userAssetIsExist() {
        this.userAsset = iUserAssetService.getOne(Wrappers.<UserAsset>lambdaQuery().eq(UserAsset::getUserId, userId));
        if (StringUtils.isEmpty(this.userAsset)) {
            iUserAssetService.save(new UserAsset(userId.intValue()));
            this.userAsset = this.iUserAssetService.getOne(Wrappers.<UserAsset>lambdaQuery().eq(UserAsset::getUserId, userId));
        }
    }
}
